<template>
  <div class="magnifier" id="magnifier1" :style="{'width': width ? width + 'px' : 'auto'}">
    <div class="magnifier-container">
      <div class="images-cover" v-for="(img, index) in photos" v-bind:key="index" v-show="imgIndex == index && !skuImage">
        <img v-lazy="img" @mouseleave="hideBigImage($event)" @mouseenter="showBigImage($event)" @mousemove="moveBigImage($event)">
      </div>
      <div class="images-cover" v-show="skuImage">
        <img alt="" :src="skuImage" @mouseleave="hideBigImage($event)" @mouseenter="showBigImage($event)" @mousemove="moveBigImage($event)">
      </div>
      <!--当前图片显示容器-->
      <div class="move-view" :style="{top: position.y + 'px', left: position.x + 'px', display: isMouseIn?'block':'none'}"></div>
      <!--跟随鼠标移动的盒子-->
    </div>
    <!-- 缩略图 -->
    <div class="magnifier-assembly">
      <div class="magnifier-btn" style="visibility: hidden;">
        <span :class="{'magnifier-btn-left': true, disabled: !leftMove}" title="向左" @click="showPrevImg()">&lt;</span>
        <span :class="{'magnifier-btn-right': true, disabled: (!rightMove || photos.length <= 4)}" title="向右" @click="showNextImg()">&gt;</span>
      </div>
      <!--按钮组-->
      <div class="magnifier-line">
        <ul class="clearfix animation03">
          <li v-for="(img, index) in photos" @click="showCurrentImage(index)" :class="{active: index == imgIndex}"  v-bind:key="index">
            <div class="small-img">
              <img class="minimg" v-lazy="img" :title="img.name"/>
            </div>
          </li>
        </ul>
      </div>
      <!--缩略图-->
    </div>
    <!-- 大图 -->
    <div class="magnifier-view" v-show="isMouseIn">
      <img v-for="(img, index) in photos" v-bind:key="index" :src="img" v-if="imgIndex == index && !skuImage" :style="{marginLeft: (-bigImagePosition.x + 'px'), marginTop: (-bigImagePosition.y + 'px')}"/>
      <img v-if="skuImage" :src="skuImage" :style="{marginLeft: (-bigImagePosition.x + 'px'), marginTop: (-bigImagePosition.y + 'px')}">
    </div>
    <!--经过放大的图片显示容器-->
  </div>
</template>

<script>
const IMG_SIZE = 450

// 移动的盒子长度
const MOVE_BOX_SIZE = 100

// 大图倍数
const TIMES = 2

export default {
  mounted() {
    window.onresize = function() {
      // 如果屏幕宽度在1200
      if (document.body.clientWidth > 1200 && this.width == 0) {
        this.imgNums = 5
        return
      }

      // 如果屏幕宽度在1200以下
      this.imgNums = 3
    }
  },
  data() {
    return {
      // 缩略图向左移动
      leftMove: false,

      // 缩略图向右移动
      rightMove: false,

      // 每个屏幕中占据图片的个数
      imgNums: 5,

      // 当前的图片对象
      imgObj: {},

      // 鼠标移入
      isMouseIn: false,

      // 当前展示的图片
      imgIndex: 0,

      // 当前展示的图片组
      imgGroupIndex: 0,

      // sku属性对应的图片
      skuImage: '',

      // 鼠标位置
      position: {
        x: 0,
        y: 0
      },

      // 大图的位置
      bigImagePosition: {
        x: 0,
        y: 0
      }
    }
  },
  props: {
    width: {
      type: Number,
      default: 0
    },
    // 商品图片
    photos: {
      type: Array,
      default: () => {
        return []
      }
    },
    skuImg: {
      type: String,
      default: ''
    }
  },
  computed: {
    /**
     * 获取大图尺寸
     *
     * @return {Object} 大图尺寸 width： 宽，height：高
     */
    getBigImageSize() {
      if (!this.imgObj.target) {
        return {
          width: 0,
          height: 0
        }
      }
      return {
        width: (this.imgObj.target.width * TIMES || 0),
        height: (this.imgObj.target.height * TIMES || 0)
      }
    }
  },
  watch: {
    skuImg() {
      this.skuImage = this.skuImg
    }
  },
  methods: {
    /**
     * 当鼠标移入的时候，展示大图
     *
     * @param {Object} $event 当前操作的图片对象
     */
    showBigImage($event) {
      // 获取最后位置
      let posi = this.getMoveViewPosition($event)

      // 记录鼠标移动的时候，鼠标位置
      this.position = {
        x: posi.x,
        y: posi.y
      }

      // 大图的位置
      this.bigImagePosition = {
        x: this.position.x * TIMES,
        y: (this.position.y - (IMG_SIZE - $event.target.height) / 2) * TIMES
      }

      // 鼠标移入
      this.isMouseIn = true
      this.imgObj = $event
    },

    /**
     * 获取鼠标移动容器的位置
     *
     * @param {Object} $event 当前图片对象
     *
     * @return {Object} 位置 x：x轴位置，y：y轴位置
     */
    getMoveViewPosition($event) {
      // x轴坐标
      let x = Math.ceil($event.clientX - $('#magnifier1').offset().left - (MOVE_BOX_SIZE / 2))

      // y轴坐标
      let y = Math.ceil(($event.clientY - $('#magnifier1').offset().top + $(document).scrollTop()) - (MOVE_BOX_SIZE / 2))

      // 鼠标超出图片区域左边
      if (x < 0) {
        x = 0
      }

      // 鼠标超出图片区域右边
      if (x > $event.target.width - MOVE_BOX_SIZE) {
        x = $event.target.width - MOVE_BOX_SIZE
      }

      // 鼠标超出图片区域上区域
      let topHeight = (IMG_SIZE - $event.target.height) / 2
      if (y < topHeight) {
        y = topHeight
      }

      // 如果鼠标超出图片区域下部分
      if ((y + MOVE_BOX_SIZE) > topHeight + $event.target.height) {
        y = topHeight + $event.target.height - MOVE_BOX_SIZE
      }

      return {
        x: x,
        y: y
      }
    },

    /**
     * 根据鼠标移动，移动大图
     *
     * @param {Object} $event 当前操作的图片对象
     */
    moveBigImage($event) {
      // 获取最后位置
      let posi = this.getMoveViewPosition($event)

      // 记录鼠标移动的时候，鼠标位置
      this.position = {
        x: posi.x,
        y: posi.y
      }

      // 大图的位置
      this.bigImagePosition = {
        x: this.position.x * TIMES,
        y: (this.position.y - (IMG_SIZE - $event.target.height) / 2) * TIMES
      }
    },

    /**
     * 当鼠标移出的时候，隐藏大图
     */
    hideBigImage($event) {
      // 鼠标移出
      this.isMouseIn = false
    },

    /**
     * 点击缩略图，展示当前的图片
     *
     * @param {Integer} $index 当前点击的图片索引
     */
    showCurrentImage($index) {
      this.imgIndex = $index
      this.skuImage = ''

      // 如果点击的是后面没有展示完成的图片，且不为第一个，则滑动下方缩略图
      if ($index % this.imgNums == 0 && $index != 0) {
        // this.showNextImg()
      }
    },

    /**
     * 展示未展示的缩略图的下一组图片
     */
    showNextImg() {
      // 如果图片长度在4以内，则不操作
      if (this.photos.length <= this.imgNums) {
        return
      }

      // 如果图片长度在8个以内，则展示最后4个
      if (this.photos.length <= this.imgNums * 2) {
        // 可以向左滑动
        this.leftMove = true

        // 不可以向左滑动
        this.rightMove = false

        document.querySelector('.magnifier-line ul').style.left = -100 * (this.photos.length - this.imgNums + 1) + 'px'
        return
      }

      // 展示向左滑动按钮
      this.leftMove = true

      // 可以向右滑动
      this.rightMove = true

      // 如果图片长度在8个以上，则每次展示4个（4个一组）
      let groupLength = Math.floor(this.photos.length / this.imgNums)
      this.imgGroupIndex < groupLength ? this.imgGroupIndex ++ : groupLength
      document.querySelector('.magnifier-line ul').style.left = -100 * this.imgGroupIndex * this.imgNums + 'px'

      // 如果是最后一组，则禁用向右滑动的
      if (this.imgGroupIndex == groupLength) {
        this.rightMove = false
      }
    },

    /**
     * 展示未展示的缩略图的上一组图片
     */
    showPrevImg() {
      // 如果图片长度在4以内，则不操作
      if (this.photos.length <= this.imgNums) {
        return
      }

      // 如果图片长度在8个以内，则展示最后4个
      if (this.photos.length <= this.imgNums) {
        // 展示向左滑动缩略图的按钮
        this.leftMove = false

        // 不可以向右滑动
        this.rightMove = true
        document.querySelector('.magnifier-line ul').style.left = '0px'
        return
      }

      // 展示向左滑动缩略图的按钮
      this.leftMove = true

      // 展示向右滑动缩略图的按钮
      this.rightMove = true

      // 如果图片长度在8个以上，则每次展示4个（4个一组）
      this.imgGroupIndex > 0 ? this.imgGroupIndex -- : 0
      document.querySelector('.magnifier-line ul').style.left = -100 * this.imgGroupIndex * this.imgNums + 'px'

      // 如果是第一组，则不展示向左按钮
      if (this.imgGroupIndex == 0) {
        this.leftMove = false
      }
    }
  }
}
</script>

<style lang="scss" scoped>
ul li{
  list-style: none;
}
img{
  border: 0;
  height: auto;
}
.small-img{
  display: flex;
  align-items:center;
  justify-content: center;
}
.clearfix:before,
.clearfix:after{
  display: table;
  line-height: 0;
  content: "";
}
.magnifier{
  position: relative;
  max-width: 455px;
}
.magnifier-container{
  width: 450px;
  height: 450px;
  overflow: hidden;
  position: relative;
  border: 1px solid #ddd;
}
.move-view{
  width: 100px;
  height: 100px;
  position: absolute;
  pointer-events:none;
  background-image: url('./images/move-box.png');
}
.images-cover{
  height: 450px;
  line-height: 450px;
  width: 450px;
  position: relative;
}
.images-cover img{
  display: inline-block;
  height: 450px;
  margin-top: -4px;
  vertical-align: middle;
}
.magnifier-assembly{
  height: 92px;
  overflow: hidden;
  position: relative;
  padding-left: 30px;
  padding-right: 30px;
}
.magnifier-btn{
  position: absolute;
  font-family: "宋体";
  width: 100%;
  top: 50%;
  left: 0;
  margin-top: -40px;
}
.magnifier-btn span{
  line-height: 60px;
  height: 60px;
  width: 20px;
  background-color: #6e6e6e;
  color: #fff;
  display: block;
  z-index: 20;
  text-align: center;
  font-size: 20px;
  cursor: pointer;
  border-radius: 3px;
}
.magnifier-btn span.disabled {
  background-color: lightgrey;
}
.magnifier-btn .magnifier-btn-left{
  float: left;
}
.magnifier-btn .magnifier-btn-right{
  float: right;
}
.magnifier-line{
  position: relative;
  overflow: hidden;
  height: 92px;
  margin-top: 13px;
}
.magnifier-line ul{
  display: block;
  font-size: 0;
  width: 1000%;
  position: absolute;
  left: 0;
  z-index: 20;
}
.magnifier-line li{
  float: left;
  cursor: pointer;
}
.magnifier-line ul > .active .small-img{
  border-color: #ec007e;
}
.small-img{
  width: 66px;
  height: 66px;
  margin: 5px 6px;
  overflow: hidden;
  border: 2px solid #ddd;
  text-align: center;
}
.small-img img{
  max-width: 100%;
  max-height: 100%;
}
.magnifier-view{
  width: 450px;
  height: 450px;
  position: absolute;
  right: -105%;
  top: 0;
  z-index: 20;
  background-color: #fff;
  overflow: hidden;
}
.magnifier-view img{
  width: 1150px;
  height: 1150px;
  display: block;
}
.animation03{
  transition: all 0.3s linear 0.15s;
  -ms-transition: all 0.3s linear 0.15s;
  -moz-transition: all 0.3s linear 0.15s;
  -webkit-transition: all 0.3s linear 0.15s;
  -o-transition: all 0.3s linear 0.15s;
}
</style>